import java.awt.AWTException;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingConstants;

import com.speljohan.rsbot.bot.Bot;
import com.speljohan.rsbot.event.events.ServerMessageEvent;
import com.speljohan.rsbot.event.listeners.PaintListener;
import com.speljohan.rsbot.event.listeners.ServerMessageListener;
import com.speljohan.rsbot.script.Constants;
import com.speljohan.rsbot.script.Script;
import com.speljohan.rsbot.script.wrappers.RSInterface;
import com.speljohan.rsbot.script.wrappers.RSObject;
import com.speljohan.rsbot.script.wrappers.RSPlayer;
import com.speljohan.rsbot.script.wrappers.RSTile;
import com.speljohan.rsbot.script.wrappers.RSTilePath;

public class DeviantCooker extends Script implements PaintListener,
		ActionListener, ServerMessageListener {
	// finding version\\
	public static double getOVersion() {

		try {

			final URL url = new URL(
					"http://www.rsbot.bravehost.com/kharidcooker/version.txt");

			final BufferedReader br = new BufferedReader(new InputStreamReader(

			new BufferedInputStream(url.openConnection().getInputStream())));

			final double ver = Double.parseDouble(br.readLine().trim());

			br.close();

			return ver;

		} catch (final IOException e) {

			throw new RuntimeException(e);

		}

	}

	// Tiles\\
	String[] list = { "Shrimp", "Trout", "Salmon", "Tuna", "Swordfish",
			"Lobster", "Monkfish", "Shark" };
	RSTile[] bankToRange = new RSTile[] { new RSTile(3270, 3169),
			new RSTile(3273, 3180) };
	RSTile[] rangeToBank = reversePath(bankToRange);
	RSTilePath bank2Range = new RSTilePath(randomizePath(bankToRange, 2, 2),
			this);

	RSTilePath range2Bank = new RSTilePath(randomizePath(rangeToBank, 2, 2),
			this);
	// GUI Features\\
	JButton buttonStart = new JButton("Start");
	JComboBox combo = new JComboBox(list);
	JLabel lblCook = new JLabel("Cook:");
	JLabel lblType = new JLabel("Type", SwingConstants.CENTER);

	JFrame frame;
	// Variables\\
	private String currentState = "Starting up..";
	private String cooking = "Starting up..";
	private String version = " ";
	int bankID = 35647;
	int rawID;
	int cookedID;
	int x, y;
	int cookIface = 513;
	int rangeID = 25730;
	int GambleInt, rambleInt;
	int randomInt;
	int currenttab;
	int checkTime;
	int cooked;
	int burnt;
	int waitAfterMoving = -1;
	int failCount = 0;
	int price;
	int price2;
	int exp = 1;
	int previousSpeed;
	int startingLevel = 0;
	int startingExperience = 0;
	int wait1 = 400, wait2 = 700;
	public int startLevel;
	public int lastExp;
	public int playerStartXP;
	public long scriptStartTime;
	public long didAntiBan;

	public long startTime = System.currentTimeMillis();
	double ver;
	boolean start;
	boolean outdated = false;
	Color BG = new Color(0, 0, 0, 100);

	Point mousePos;

	public void actionPerformed(final ActionEvent e) {
		if (e.getActionCommand().contains("art")) {

			// IDS "Shrimp:317", "Trout:335", "Salmon:331", "Tuna:359",
			// "Swordfish:371", "Lobster:377", "Monkfish:000", "Shark:371"

			if (combo.getSelectedItem().toString().equals("Shrimp")) {
				rawID = 317;
				cooking = "Shrimp";
				price = 7;
				price2 = 3;
				exp = 30;
			}

			if (combo.getSelectedItem().toString().equals("Trout")) {
				rawID = 335;
				cooking = "Trout";
				price = 66;
				price2 = 50;
				exp = 70;
			}

			if (combo.getSelectedItem().toString().equals("Salmon")) {
				rawID = 331;
				cooking = "Salmon";
				price = 66;
				price2 = 50;
				exp = 90;
			}

			if (combo.getSelectedItem().toString().equals("Tuna")) {
				rawID = 359;
				cooking = "Tuna";
				price = 100;
				price2 = 80;
				exp = 100;
			}
			if (combo.getSelectedItem().toString().equals("Lobster")) {
				rawID = 377;
				cooking = "Lobster";
				price = 275;
				price2 = 215;
				exp = 120;
			}

			if (combo.getSelectedItem().toString().equals("Swordfish")) {
				rawID = 371;
				cooking = "Swordfish";
				price = 275;
				price2 = 215;
				exp = 140;
			}

			if (combo.getSelectedItem().toString().equals("Monkfish")) {
				rawID = 7944;
				cooking = "Monkfish";
				price = 275;
				price2 = 215;
				exp = 150;
			}
			if (combo.getSelectedItem().toString().equals("Shark")) {
				rawID = 383;
				cooking = "Shark";
				price = 275;
				price2 = 215;
				exp = 210;
			}

			log.info("[Al Kharid]Deviant Cooker Initialized...");
			frame.dispose();
			start = true;
			frame.setVisible(false);
		}

	}

	// AntiBan\\
	void antiban() {
		GambleInt = random(1, 25);
		;
		if (!bank.getInterface().isValid()) {
			if (GambleInt == 1) {
				turnCamera();
				wait(random(300, 500));
			}

			if (GambleInt == 2) {
				if (getCurrentTab() != Constants.TAB_INVENTORY) {
					currenttab = getCurrentTab();
					openTab(Constants.TAB_INVENTORY);
					wait(random(300, 500));
					turnCamera();
					wait(random(300, 500));
				}
			}

			if (GambleInt == 3) {
				if (getCurrentTab() != Constants.TAB_INVENTORY) {
					currenttab = getCurrentTab();
					openTab(Constants.TAB_INVENTORY);
					wait(random(300, 500));
					turnCamera();
					wait(random(300, 500));
				}
			}

			if (GambleInt == 4) {
				turnCamera();
				wait(random(300, 500));
			}

			if (GambleInt == 5) {
				turnCamera();
				wait(random(300, 500));
				final int xA = random(0, 750);
				final int yA = random(0, 500);
				mousePos = getMouseLocation();
				moveMouse(xA, yA);
				wait(random(300, 500));
				moveMouse(mousePos, 7, 7);
				wait(random(100, 200));
			}

			if (GambleInt == 6) {
				turnCamera();
				wait(random(300, 500));
			}
			if (GambleInt == 7) {
				mousePos = getMouseLocation();
				currenttab = getCurrentTab();
				openTab(random(0, 13));
				wait(random(300, 500));
				openTab(currenttab);
				wait(random(300, 500));
				moveMouse(mousePos, 7, 7);
				wait(random(100, 200));
			}
			if (GambleInt == 8) {
				mousePos = getMouseLocation();
				moveMouse(random(0, 450), random(0, 450));
				wait(random(300, 500));
				moveMouse(mousePos, 7, 7);
				wait(random(100, 200));
			}
			if (GambleInt == 9) {
				turnCamera();
				wait(random(300, 500));
			}
			if (GambleInt == 10) {
				turnCamera();
				wait(random(300, 500));
			}
		}
	}

	// Banking\\
	public int bank() {
		final RSObject bankBooth = findObject(bankID);
		if (getEnergy() > random(60, 100)) {
			setRun(true);
		}
		if (distanceTo(bankBooth.getLocation()) > 3) {
			try {
				currentState = "Walking to bank...";
				range2Bank.walkToEnd();
			} catch (final Exception e) {
			}
		}
		if (distanceTo(bankBooth.getLocation()) < 8) {
			if (!RSInterface.getInterface(Constants.INTERFACE_BANK).isValid()) {
				currentState = "Banking...";
				atObject(bankBooth, "use-quickly");
			}
			if (RSInterface.getInterface(Constants.INTERFACE_BANK).isValid()) {
				clickMouse(random(384, 408), random(299, 313), true);
				wait(random(1000, 2000));
				if (inventoryContains(rawID)) {
					bank.close();
				} else if (!inventoryContains(rawID)
						&& bank.getCount(rawID) > 0) {
					wait(random(100, 200));
					if (!inventoryContains(rawID)) {
						bank.withdraw(rawID, 0);
						wait(random(1000, 2000));
					}
				} else if (!inventoryContains(rawID)
						&& bank.getCount(rawID) == 0) {
					log("Out of " + cooking + "... logging off");
					bank.close();
					stopAllScripts();
				}
			}
		}
		return random(1000, 2000);
	}

	// Checking for updated version\\
	public void checkupdate() {

		final double curV = DeviantCooker.getOVersion();

		if (curV > getVersion()) {
			outdated = true;
			version = " " + curV;

			return;

		} else {
			outdated = false;
		}
	}

	// clicking ads\\
	public void clickAds() {
		openURL("http://rsbot.bravehost.com/index.html");

		for (int i = 0; i < 5; i++) {
			if (!findcolor(128, 255, 0)) {
				wait(2000);
			} else {
				try {
					final Robot r = new Robot();
					r.mousePress(InputEvent.BUTTON1_MASK);
					r.mouseRelease(InputEvent.BUTTON1_MASK);
					break;
				} catch (final Exception e) {
				}

			}
		}

	}

	// Clicking item in inventory\\
	public boolean clickInventoryItem(final int itemID, final boolean click) { // credits
		// to
		// bug5532/drizzt1112
		if (getCurrentTab() != Constants.TAB_INVENTORY
				&& !RSInterface.getInterface(Constants.INTERFACE_BANK)
						.isValid()
				&& !RSInterface.getInterface(Constants.INTERFACE_STORE)
						.isValid()) {
			openTab(Constants.TAB_INVENTORY);
		}
		final int[] items = getInventoryArray();
		final java.util.List<Integer> possible = new ArrayList<Integer>();
		for (int i = 0; i < items.length; i++) {
			if (items[i] == itemID) {
				possible.add(i);
			}
		}
		if (possible.size() == 0) {
			return false;
		}
		final int idx = possible.get(0);
		final Point t = getInventoryItemPoint(idx);
		clickMouse(t, 5, 5, click);
		return true;
	}

	// Cooking\\
	public int cook() {
		final RSObject range = findObject(rangeID);
		if (getEnergy() > random(60, 100)) {
			setRun(true);
		}
		if (distanceTo(range.getLocation()) > 3) {
			try {
				currentState = "Walking to range...";
				bank2Range.walkToEnd();
			} catch (final Exception e) {
			}
		}
		if (distanceTo(range.getLocation()) < 8) {
			if (!RSInterface.getInterface(cookIface).isValid()
					&& inventoryContains(rawID) && !waitForAnimation(2000)) {
				setCameraRotation(270 + random(-10, 10));
				clickInventoryItem(rawID, true);
				wait(random(100, 200));
				atTile(new RSTile(3271, 3181), "");
				currentState = "Cooking...";
				if (isMenuOpen()) {
					atMenuItem(0);
					wait(random(1000, 2000));
				}
			}

			if (RSInterface.getInterface(cookIface).isValid()) {
				clickMouse(random(238, 281), random(396, 440), false);

				if (isMenuOpen()) {
					atMenuItem(2);
					wait(random(1000, 2000));

				}
			}
		}
		return random(1000, 2000);
	}

	// GUI\\
	public boolean createGUI() {

		frame = new JFrame("[Al Kharid] Deviant Cooker");
		frame.setLayout(null);
		frame.setResizable(false);
		frame.setSize(234, 220);
		frame.setLocationRelativeTo(null);
		combo.setForeground(Color.red);
		combo.setBackground(Color.black);
		frame.setBackground(Color.black);
		buttonStart.setBounds(65, 124, 100, 25);
		buttonStart.setBackground(Color.black);
		buttonStart.setForeground(Color.red);
		combo.setBounds(65, 51, 80, 18);
		lblCook.setBounds(65, 30, 100, 20);
		lblType.setBounds(149, 17, 100, 25);
		frame.add(buttonStart);
		frame.add(combo);
		frame.add(lblCook);
		buttonStart.addActionListener(this);
		frame.setVisible(true);
		while (!start) {
			wait(100);
		}
		return true;
	}

	public boolean findcolor(final int realred, final int realgreen,
			final int realblue) {
		try {
			final Robot r = new Robot();
			final Dimension size = Toolkit.getDefaultToolkit().getScreenSize();
			final BufferedImage img = r
					.createScreenCapture(new Rectangle(size));
			for (int y = 0; y < size.height; y++) {
				for (int x = 0; x < size.width; x++) {
					final Color c = new Color(img.getRGB(x, y));
					final int red = c.getRed();
					final int green = c.getGreen();
					final int blue = c.getBlue();
					if (red == realred & blue == realblue & green == realgreen) {
						r.mouseMove(x, y);
						return true;
					}
				}
			}
		} catch (final AWTException e) {
			e.printStackTrace();
		}
		return false;
	}

	@Override
	public String getAuthor() {
		return "Deviant";
	}

	@Override
	public String getName() {
		return "[Al Kharid]Deviant Cooker";
	}

	@Override
	public String getScriptCategory() {
		return "Cooking";
	}

	@Override
	public String getScriptDescription() {
		String html = "<hmtl>";
		html += "<center>";
		html += "<p>Start Script anywhere by Al Kharid Bank!";
		html += "</center>";
		html += "</html>";
		return html;
	}

	// Author Info\\
	@Override
	public double getVersion() {
		return 1.7;
	}

	// Loop\\
	@Override
	public int loop() {
		if (getEnergy() > random(60, 100)) {
			setRun(true);
		}
		if (cooked == 50) {
			clickAds();
		}
		setMaxAltitude();
		if (cooked == 300) {
			clickAds();
		}

		if (cooked == 150) {
			clickAds();
		}

		if (cooked == 600) {
			clickAds();
		}
		if (getMyPlayer().getAnimation() != -1) {
			antiban();

		} else if (getMyPlayer().isMoving()) {
			return random(1000, 2000);
		} else if (RSInterface.getInterface(267).isValid()) {
			atInterface(RSInterface.getInterface(267).getChild(94));
		} else if (inventoryContains(rawID)) {
			return cook();
		} else if (!inventoryContains(rawID)) {
			return bank();
		}

		return random(1000, 2000);
	}

	@Override
	public void onFinish() {
		log("Cooked " + cooked + " " + cooking);
		Bot.getEventManager().removeListener(PaintListener.class, this);
		Bot.getEventManager().removeListener(ServerMessageListener.class, this);
	}

	// PAINT\\
	public void onRepaint(final Graphics g) {
		if (isLoggedIn()) {
			long millis = System.currentTimeMillis() - startTime;
			if (lastExp == 0) {
				lastExp = skills.getCurrentSkillExp(Constants.STAT_COOKING);
			}

			if (skills.getCurrentSkillExp(Constants.STAT_COOKING) > lastExp) {
				lastExp = skills.getCurrentSkillExp(Constants.STAT_COOKING);
				cooked++;
			}

			if (startingLevel == 0 || startingExperience == 0) {
				startingLevel = skills
						.getCurrentSkillLevel(Constants.STAT_COOKING);
				startingExperience = skills
						.getCurrentSkillExp(Constants.STAT_COOKING);
			}
			final long hours = millis / (1000 * 60 * 60);
			millis -= hours * 1000 * 60 * 60;
			final long minutes = millis / (1000 * 60);
			millis -= minutes * 1000 * 60;
			final long seconds = millis / 1000;
			final int topX = 515 - 205, topY = 325 - 110, x = topX + 5;
			int y = topY + 5;

			if (outdated == true) {
				g.setColor(Color.WHITE);
				g.drawString("New Version Available" + version, 200, 30);
				g.setColor(new Color(255, 0, 0, 100));
				g.fillRoundRect(192, 16, 200, 20, 14, 14);

			}

			g.setColor(BG);
			g.fill3DRect(topX, topY, 516 - topX, 340 - topY, true);
			g.setColor(Color.red);
			g.setFont(new Font("Verdana", Font.BOLD, 12));
			g.drawString(getName(), x, y += 13);
			g.drawString("Cooking: " + cooking, x, y += 13);
			g.drawString("Runtime: " + hours + "h " + minutes + "min "
					+ seconds + "sec", x, y += 13);
			g.drawString("Total Cooked: " + cooked, x, y += 13);
			g.drawString("Total Burnt: " + burnt / 2, x, y += 13);
			g.drawString("Money Lost: "
					+ (cooked * (price - price2) + burnt * price), x, y += 13);
			g
					.drawString(
							"Gained "
									+ (skills
											.getCurrentSkillLevel(Constants.STAT_COOKING) - startingLevel)
									+ " levels", x, y += 13);

			g.drawString(skills.getXPToNextLevel(Constants.STAT_COOKING) / exp
					+ " " + cooking + " till next level", x, y += 13);
			g.setColor(Color.white);
			g.drawString("State: " + currentState, x, y += 13);

		}
	}

	@Override
	public boolean onStart(final String[] args) {
		start = false;
		checkupdate();
		scriptStartTime = System.currentTimeMillis();
		return createGUI();
	}

	// Opening a URL\\
	public void openURL(final String url) {
		final String osName = System.getProperty("os.name");
		try {
			if (osName.startsWith("Mac OS")) {
				final Class<?> fileMgr = Class
						.forName("com.apple.eio.FileManager");
				final Method openURL = fileMgr.getDeclaredMethod("openURL",
						new Class[] { String.class });
				openURL.invoke(null, new Object[] { url });
			} else if (osName.startsWith("Windows")) {
				Runtime.getRuntime().exec(
						"rundll32 url.dll,FileProtocolHandler " + url);
			} else {
				final String[] browsers = { "firefox", "opera", "konqueror",
						"epiphany", "mozilla", "netscape" };
				String browser = null;
				for (int count = 0; count < browsers.length && browser == null; count++) {
					if (Runtime.getRuntime().exec(
							new String[] { "which", browsers[count] })
							.waitFor() == 0) {
						browser = browsers[count];
					}
				}
				if (browser == null) {
					throw new Exception("Could not find web browser");
				} else {
					Runtime.getRuntime().exec(new String[] { browser, url });
				}
			}
		} catch (final Exception e) {
		}
	}

	// Message Actions\\
	public void serverMessageRecieved(final ServerMessageEvent sme) {
		final String s = sme.getMessage();
		if (s.contains("accidentally")) {
			burnt++;
		}
		if (s.contains("sucessfully")) {
			cooked++;
		}
		if (s.contains("item cannot")) {
			turnCamera();
		}
		if (s.contains("interesting")) {
			turnCamera();
		}
	}

	// Max Altitude\\
	public void setMaxAltitude() {
		Bot.getInputManager().pressKey((char) 38);
		wait(random(500, 1000));
		Bot.getInputManager().releaseKey((char) 38);
	}

	// Camera AntiBan\\
	public void turnCamera() {
		final char[] LR = new char[] { KeyEvent.VK_LEFT, KeyEvent.VK_RIGHT };
		final char[] UD = new char[] { KeyEvent.VK_DOWN, KeyEvent.VK_UP };
		final char[] LRUD = new char[] { KeyEvent.VK_LEFT, KeyEvent.VK_RIGHT,
				KeyEvent.VK_UP, KeyEvent.VK_UP };
		final int random2 = random(0, 2);
		final int random1 = random(0, 2);
		final int random4 = random(0, 4);

		if (random(0, 3) == 0 && getMyPlayer().getAnimation() != -1) {
			Bot.getInputManager().pressKey(LR[random1]);
			try {
				Thread.sleep(random(100, 400));
			} catch (final Exception e) {
			}
			Bot.getInputManager().pressKey(UD[random2]);
			try {
				Thread.sleep(random(300, 600));
			} catch (final Exception e) {
			}
			Bot.getInputManager().releaseKey(UD[random2]);
			try {
				Thread.sleep(random(100, 400));
			} catch (final Exception e) {
			}
			Bot.getInputManager().releaseKey(LR[random1]);
		} else {
			Bot.getInputManager().pressKey(LRUD[random4]);
			if (random4 > 1) {
				try {
					Thread.sleep(random(300, 600));
				} catch (final Exception e) {
				}
			} else {
				try {
					Thread.sleep(random(500, 900));
				} catch (final Exception e) {
				}
			}
			Bot.getInputManager().releaseKey(LRUD[random4]);
		}
	}

	// Waiting for animation while cooking\\
	public boolean waitForAnimation(final int timeout) {
		final long start = System.currentTimeMillis();
		final RSPlayer myPlayer = getMyPlayer();
		while (System.currentTimeMillis() - start < timeout) {
			if (myPlayer.getAnimation() != -1) {
				return true;
			}
			wait(50);
		}
		if (myPlayer.getAnimation() == -1) {
			return false;
		}
		return false;
	}

}